from flask import get_flashed_messages, request, flash, render_template, redirect, url_for, session
from models.tipoItem import metadata, TipoItem
from models.atributoTipo import metadata, AtributoTipo
from models.database import db_session
import sys
#import bz2

from models.tipoItemManager import TipoItemManager
from models.tipoCampoManager import TipoCampoManager
from models.atributoTipoManager import AtributoTipoManager
from models.proyectoManager import ProyectoManager
from models.faseManager import FaseManager
proyectoMgr= ProyectoManager()
faseMgr= FaseManager()
tipoItemMgr = TipoItemManager()
tipoCampoMgr = TipoCampoManager()
atributoTipoMgr = AtributoTipoManager()


"""
Clase que contiene los metodos relacionados con la gestion de tipos de item del sistema
"""

def abmTipoItem():
    """ Metodo encargado de gestion de tipos de item de un proyecto """
    filtro=""
    if request.method == "POST":
        idfase = request.form["idfase"]
        filtro = request.form["filtro"]
        fase = faseMgr.getFase(idfase)
        idproyecto = session['idproyecto']
        proyecto = proyectoMgr.getProyecto(idproyecto)
        return paginarTipoItem(idfase, fase, 1, filtro, proyecto = proyecto, action= "abmTipoItem")
    if request.method == "GET":
        idproyecto = session['idproyecto']
        proyecto = proyectoMgr.getProyecto(idproyecto)
        if session['idfase']:
            if request.args.getlist("filtro"):
                filtro = request.args.getlist("filtro")[0]
            pagina = 1
            if request.args.getlist("pagina"):
                pagina = request.args.getlist("pagina")[0]
            idfase = session['idfase']
            fase = faseMgr.getFase(idfase)
            return paginarTipoItem(idfase, fase,pagina , filtro, proyecto = proyecto, action= "abmTipoItem")
        else:
            if session['idproyecto']:
                flash(u"Seleccionar una fase del proyecto antes de realizar la operaci\u00f3n", "error")
            else:
                flash(u"Seleccionar un proyecto antes de realizar la operaci\u00f3n", "error")
            return redirect(url_for("configurarFase", action= "abmTipoItem"))

def crearTipoItem():
    """ Metodo encargado de guardar un tipo de item """
    
    if request.method == "POST":
        nombre = request.form["nombre"]
        codigo = request.form["codigo"]
        descripcion = request.form["descripcion"]
        idfase = request.form["idfase"]
        fase = faseMgr.getFase(idfase)
        tipoItem = TipoItem(codigo= codigo, nombre=nombre, descripcion= descripcion)
        tipoItem.idfase = idfase
        if request.form.getlist("atri"):
            lista = request.form.getlist("atri")
            atributo=[]
            for x in lista:
                atributo.append(atributoTipoMgr.getAtributoTipo(int(x)))
            tipoItem.atributos = atributo
            tipoItemMgr.guardarTipoItem(tipoItem)
        return redirect(url_for("abmTipoItem", idfase=idfase, filtro = request.form["filtro"]))
    else:
        idfase = request.args.getlist("idfase")[0]
        nombre = ""
        descripcion=""
        codigo=""
        lista=[]
        if request.args.getlist("descripcion"):
            descripcion = request.args.getlist("descripcion")[0]
        if request.args.getlist("nombre"):
            nombre = request.args.getlist("nombre")[0]
        if request.args.getlist("codigo"):
            codigo = request.args.getlist("codigo")[0]   
        idatributos=""
        atributos=[]
        if request.args.getlist("list"):
            idatributos = request.args.getlist("list")[0]
            atributos =[]
            tam=len(idatributos)
            idatributos= idatributos[1:tam-1]
            atributosid=idatributos.split(",")
            
            for i in xrange(0, len(atributosid)):
                if atributosid[i] != "":
                    atributo = atributoTipoMgr.getAtributoTipo(atributosid[i])
                    atributos.append(atributo)
        return render_template("crearTipoItem.html", codigo=codigo, nombre=nombre, descripcion=descripcion,lista=atributos, idfase=idfase, filtro = request.args.getlist("filtro")[0])

def agregarAtributoTipo():
    """ Metodo encargado de guardar un atributo tipo """
    
    if request.method == "POST":
        nombre = request.form["nombre"]
        codigo = request.form["codigo"]
        descripcion = request.form["descripcion"]
        campo = request.form["campo"]
        tamanho = request.form["tamanho"]
        idtipocampo = request.form["idtipocampo"]
        idfase = request.form["idfase"]
        tipoCampo = tipoCampoMgr.getTipoCampo(idtipocampo)
        atributoTipo = AtributoTipo(campo, tamanho)
        atributoTipo.tipocampo= tipoCampo
        atributoTipoMgr.guardarAtributoTipo(atributoTipo)
        idatributos = []
        if request.form.getlist("list"):
            idatributos = request.form.getlist("list")
        atributos =[]
        for i in xrange(0, len(idatributos)):
            if idatributos[i] != "":
                atributo = atributoTipoMgr.getAtributoTipo(idatributos[i])
                atributos.append(atributo)
        atributos.append(atributoTipo)
        return render_template("crearTipoItem.html", lista=atributos, codigo=codigo, nombre=nombre, descripcion=descripcion, idfase=idfase, filtro = request.form["filtro"])
    else:
        idfase = request.args.getlist("idfase")[0]
        nombre = request.args.getlist("nombre")[0]
        codigo = request.args.getlist("codigo")[0]
        descripcion = request.args.getlist("descripcion")[0]
        idatributos = request.args.getlist("list")[0]
        aux = idatributos.split(",")
        lista = []
        for a in xrange(0, len(aux)-1):
            lista.append(int(aux[a]))

        tiposcampo = tipoCampoMgr.getTipoCampos()
        return render_template("agregarAtributoTipo.html",lista=lista,codigo=codigo, nombre=nombre, descripcion=descripcion , idfase=idfase, filtro = request.args.getlist("filtro")[0], tiposcampo=tiposcampo)

def agregarAtributoTipoAsignado():
    """ Metodo encargado de agregar un atributo tipo al tipo de item """
    if request.method == "POST":
        campo = request.form["campo"]
        tamanho = request.form["tamanho"]
        filtro = request.form["filtro"]
        idtipocampo = request.form["idtipocampo"]
        idtipoitem = request.form["idtipoitem"]
        idfase = request.form["idfase"]
        tipoCampo = tipoCampoMgr.getTipoCampo(idtipocampo)
        atributoTipo = AtributoTipo(campo, tamanho)
        atributoTipo.tipocampo= tipoCampo
        tipoItem = tipoItemMgr.getTipoItem(idtipoitem)
        tipoItem.atributos.append(atributoTipo)
        tipoItemMgr.agregarAtributoTipoItem(tipoItem)
        return redirect(url_for("modificarTipoItem",idtipoitem=idtipoitem, tipoItem=tipoItem, idfase=idfase, filtro=filtro))
    else:
        idfase = request.args.getlist("idfase")[0]
        idtipoitem = request.args.getlist("idtipoitem")[0]
        tiposcampo = tipoCampoMgr.getTipoCampos()
        return render_template("agregarAtributoTipoAsignado.html", idfase=idfase, filtro = request.args.getlist("filtro")[0], tiposcampo=tiposcampo, idtipoitem=idtipoitem)

def importarTipoItem():
    """ Metodo encargado de importar un tipo de item de otro proyecto """
    
    if request.method == "GET":
        idfase = request.args.getlist("idfase")[0]
        tipos = tipoItemMgr.getTipoItemNoFase(idfase)
        return render_template("importarTipoItem.html", tipos=tipos,idfase=idfase, filtro = request.args.getlist("filtro")[0] )
    if request.method == "POST":
        idtipoitem = request.form["valor"]
        tipoItem = tipoItemMgr.getTipoItem(idtipoitem)
        nombre = tipoItem.nombre
        codigo = tipoItem.codigo
        descripcion = tipoItem.descripcion
        idfase = request.form["idfase"]
        fase = faseMgr.getFase(idfase)
        tipoItemImportado = TipoItem(codigo=codigo, nombre=nombre, descripcion=descripcion)
        tipoItemImportado.fase = fase
        atributos =[]
        for atributo in tipoItem.atributos:
            atributoCopia = AtributoTipo(campo=atributo.campo,tamanho=atributo.tamanho)
            atributoCopia.tipoitem = tipoItemImportado
            atributoCopia.tipocampo = atributo.tipocampo        
            atributos.append(atributoCopia)
        tipoItemImportado.atributos = atributos
        tipoItemMgr.guardarTipoItem(tipoItemImportado)
        return redirect(url_for("abmTipoItem", idfase=idfase, filtro = request.form["filtro"]))

def modificarTipoItem():
    session = db_session()
    """ Metodo encargado de modificar un tipo de item """
    
    if request.method == "GET":
        idtipoitem = request.args.getlist("idtipoitem")[0]
        tipoItem = tipoItemMgr.getTipoItem(idtipoitem)
        idfase = request.args.getlist("idfase")[0]
        atributos = atributoTipoMgr.getAtributoItemPorTipo(idtipoitem)
        return render_template("modificarTipoItem.html", atributos=atributos,idfase=idfase, tipoItem = tipoItem, filtro = request.args.getlist("filtro")[0] )
    if request.method == "POST":
        idtipoitem = request.form["idtipoitem"]
        tipoItem = tipoItemMgr.getTipoItem(idtipoitem)
        tipoItem.codigo = request.form["codigo"]
        tipoItem.nombre = request.form["nombre"]
        tipoItem.descripcion = request.form["descripcion"]
        idfase = request.form["idfase"]
        fase = faseMgr.getFase(idfase)
        tipoItem.fase = fase
        tipoItemMgr.guardarTipoItem(tipoItem)
        mensajes = get_flashed_messages(with_categories= True)
        categoria, mensaje = mensajes[0]
        if categoria == "error":
            flash(mensaje, categoria)
        else:
            flash("Modificado exitosamente");
        return redirect(url_for("abmTipoItem", idfase=idfase, filtro = request.form["filtro"]))

def modificarAtributoTipo():
    """ Metodo encargado de modificar un atributo """
    
    if request.method == "POST":
        campo = request.form["campo"]
        tamanho = request.form["tamanho"]
        idtipocampo = request.form["idtipocampo"]
        idatributotipo = request.form["idatributotipo"]
        idtipoitem = request.form["idtipoitem"]
        tipoItem=tipoItemMgr.getTipoItem(idtipoitem)
        idfase = request.form["idfase"]
        tipoCampo = tipoCampoMgr.getTipoCampo(idtipocampo)
        atributoTipo = atributoTipoMgr.getAtributoTipo(idatributotipo)
        atributoTipo.tipocampo= tipoCampo
        atributoTipo.campo = campo
        atributoTipo.tamanho = tamanho
        atributoTipoMgr.guardarAtributoTipo(atributoTipo)
        atributos = atributoTipoMgr.getAtributoItemPorTipo(idtipoitem)
        return render_template("modificarTipoItem.html",atributos=atributos, tipoItem=tipoItem, idfase=idfase, filtro = request.form["filtro"])
    else:
        idfase = request.args.getlist("idfase")[0]
        idatributotipo = request.args.getlist("idatributotipo")[0]
        idtipoitem = request.args.getlist("idtipoitem")[0]
        atributo = atributoTipoMgr.getAtributoTipo(idatributotipo)
        tiposcampo = tipoCampoMgr.getTipoCampos()
        return render_template("modificarAtributoTipo.html",idtipoitem=idtipoitem,atributo = atributo, idfase=idfase, filtro = request.args.getlist("filtro")[0], tiposcampo=tiposcampo)

def eliminarTipoItem():
    """ Metodo encargado de eliminar un tipo de item """
    
    if request.method == "POST":
        idtipoitem = request.form["idtipoitem"]
        tipoItemMgr.eliminarTipoItem(idtipoitem)
        idfase = request.form["idfase"]
        flash("Tipo de Item eliminado exitosamente")
        return redirect(url_for("abmTipoItem", idfase=idfase, filtro = request.form["filtro"]))
    if request.method == "GET":
        idtipoitem = request.args.getlist("idtipoitem")[0]
        tipoItem = tipoItemMgr.getTipoItem(idtipoitem);
        idfase = request.args.getlist("idfase")[0]
        atributos = atributoTipoMgr.getAtributoItemPorTipo(idtipoitem)
        return render_template("eliminarTipoItem.html", atributos=atributos,tipoItem=tipoItem, idfase=idfase, filtro= request.args.getlist("filtro")[0])

def eliminarAtributoTipo():
    """ Metodo encargado de eliminar un atributo tipo de la base de datos """
    
    if request.method == "POST":
        idatributotipo = request.form["idatributotipo"]
        nombre = request.form["nombre"]
        descripcion = request.form["descripcion"]
        atributo = atributoTipoMgr.getAtributoTipo(idatributotipo)
        if request.form["list"]:
            idatributos = request.form["list"]
        atributos =[]
        idatributos = idatributos.split(",")
        for i in xrange(0, len(idatributos)):
            if idatributos[i] != "":
                if idatributos[i] != idatributotipo:
                    atributo = atributoTipoMgr.getAtributoTipo(idatributos[i])
                    atributos.append(atributo)
        atributoTipoMgr.eliminarAtributoTipo(idatributotipo)
        idfase = request.form["idfase"]
        flash("Atributo Tipo eliminado exitosamente")
        return render_template("crearTipoItem.html", lista=atributos, idfase=idfase, filtro = request.form["filtro"], nombre=nombre, descripcion=descripcion)
    if request.method == "GET":
        idatributotipo = request.args.getlist("idatributotipo")[0]
        atributoTipo = atributoTipoMgr.getAtributoTipo(idatributotipo);
        idfase = request.args.getlist("idfase")[0]
        lista = []
        if request.args.getlist("list"):
            lista= request.args.getlist("list")[0]
        nombre= request.args.getlist("nombre")[0]
        descripcion= request.args.getlist("descripcion")[0]
        return render_template("eliminarAtributoTipo.html",lista=lista,atributoTipo=atributoTipo, idfase=idfase, filtro= request.args.getlist("filtro")[0], nombre=nombre, descripcion=descripcion)

def eliminarAtributoTipoAsignado():
    """ Metodo encargado de eliminar un atributo tipo de un tipo de item """
    if request.method == "GET":
        idatributotipo = request.args.getlist("idatributotipo")[0]
        atributoTipoMgr.eliminarAtributoTipo(idatributotipo)
        idtipoitem = request.args.getlist("idtipoitem")[0]
        tipoItem=tipoItemMgr.getTipoItem(idtipoitem)
        idfase = request.args.getlist("idfase")[0]
        atributos = atributoTipoMgr.getAtributoItemPorTipo(idtipoitem)
        return redirect(url_for("modificarTipoItem",idtipoitem=idtipoitem, tipoItem=tipoItem, idfase=idfase, filtro= request.args.getlist("filtro")[0]))

def consultarTipoItem():
    """ Metodo encargado de consultar los datos de un tipo de item """
    
    if request.method == "GET":
        idtipoitem = request.args.getlist("idtipoitem")[0]
        tipoItem = tipoItemMgr.getTipoItem(idtipoitem)
        idfase = request.args.getlist("idfase")[0]
        atributos = atributoTipoMgr.getAtributoItemPorTipo(idtipoitem)
        return render_template("consultarTipoItem.html",atributos=atributos, idfase=idfase, tipoItem = tipoItem, filtro = request.args.getlist("filtro")[0])
    else:
        idfase = request.form["idfase"]
        return redirect(url_for("abmTipoItem", idfase=idfase, filtro = request.form["filtro"]))

def paginarTipoItem(idfase, fase, pagina, filtro, proyecto, action):
    """ Metodo encargado de la busqueda de tipos de item a partir de un filtro """
    porPagina= 5
    pagina = int(pagina)
    total = tipoItemMgr.getTipoItemPaginado(idfase, nombre=filtro, desde=None, hasta=None)
    if total % porPagina == 0:
        cantPaginas= total/porPagina
    else:
        resto = total % porPagina
        subtotal = (total-resto)
        cantPaginas= (subtotal/porPagina) + 1
    hasta = pagina * porPagina
    desde = hasta - porPagina
    tipos = tipoItemMgr.getTipoItemPaginado(idfase, filtro, desde, hasta)
    return render_template("abmTipoItem.html", lista = tipos, idfase = idfase, fase =fase,\
        filtro = filtro, form=request.form, primera=1, ultima= cantPaginas, ant= pagina-1,\
        sig=pagina +1, cantPaginas = cantPaginas, pagina = pagina, proyecto = proyecto, action=action)
  
